package algorithms;

import java.util.ArrayList;

import templates.Operator;
import templates.State;

public class DepthSearch<Template> extends Algorithm<Template>{
	public DepthSearch(State<Template> iState, ArrayList<State<Template>> fStates,
			ArrayList<Operator<Template>> opr, String log) {
		super(iState, fStates, opr, log);
	}
	private boolean switcher ;
	private boolean result=false;

	private boolean expand(State<Template> thisState){
		int counter=0;
		if (isSwitcher()){
			counter=getIndex(thisState.getRedoOperator())+1; 
			setSwitcher(false); 
			}
		if (getIndex(thisState.getCurrentOperator())==operatorNumber) { 
			counter=0; 
			}
		for(int i=counter;i<=operatorNumber;i++){
			if (operators.get(i).available(thisState.getCurrentState())) {
					State<Template> auxiliary=new State<Template>(operators.get(i).execute(thisState.getCurrentState()), operators.get(i));
					if (!found(auxiliary)) { 
						btStack.push(auxiliary); 
						return true; 
					}
				}
		}
		return false;
	}
	
	private boolean solve(State<Template> thisState){
		if( !isSwitcher()) 
			setSwitcher(false);
		if(thisState!=null){
			if(expand(thisState)){
				if (solutionFound(btStack.peek())) {
					result=true; 
					return true;
					} 
				}
			else { 
				Operator<Template> auxiliaryOperator=btStack.peek().getCurrentOperator();				
				if (btStack.size()>1)
					btStack.pop();
				State<Template> auxiliaryState=btStack.pop();
				auxiliaryState.setRedoOperator(auxiliaryOperator);
				btStack.push(auxiliaryState);
				setSwitcher(true);
				}		
			solve(btStack.peek());
		} 
		return false;
	}

	private boolean setSwitcher(boolean switcher) {
		this.switcher = switcher;
		return switcher;
	}

	public boolean isSwitcher() {
		return switcher;
	}

	public boolean solveProblem() {
		solve(initialState);
		if (result==true) 
			return true;
		return false;
	}
	public void init(){
		setSwitcher(false);
	}	
}
